#include <QtGui>

#include "mainwindow.h"


MainWindow::MainWindow()
{
    imageLabel = new QLabel;
//    imageLabel->setBackgroundRole(QPalette::Base);
    imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);

    scrollArea = new QScrollArea;
    scrollArea->setBackgroundRole(QPalette::Dark);
    scrollArea->setWidget(imageLabel);
    setCentralWidget(scrollArea);

    createActions();
    createMenus();

    setWindowTitle(tr("Image Viewer"));
    resize(600, 400);
}

void MainWindow::open()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                                    tr("Open Image"),
                                    QDir::homePath(),
                                    tr("Image Files (*.png *.jpg *.bmp *.tiff)"));
    if (!fileName.isEmpty()) {
        QImage image(fileName);
        if (image.isNull()) {
            QMessageBox::information(this, tr("Image Viewer"),
                                     tr("Cannot load %1.").arg(fileName));
            return;
        }

        QFileInfo temp(fileName);
        pathname = temp.absolutePath();

        imageLabel->setPixmap(QPixmap::fromImage(image));

//        scaleFactor = 1.0;

        printAct->setEnabled(true);
        saveAct->setEnabled(true);
        updateActions();
        imageLabel->adjustSize();
    }
}

void MainWindow::save()
{
    QString fileName = QFileDialog::getSaveFileName(this,
                        tr("Choose a file name"),
                        pathname,
                        tr("JPEG (*.jpg *.jpeg)"));
    if (fileName.isEmpty())
        return;
    QImageWriter image(fileName);
    if (!image.canWrite()) {
        QMessageBox::information(this, tr("Luvlena Image Editor"),
                                 tr("Unable to write %1: %2")
                                 .arg(fileName)
                                 .arg(image.errorString()));
        return;
    }

    image.write(imageLabel->pixmap()->toImage());

    statusBar()->showMessage(tr("Saved '%1'").arg(fileName), 2000);
}

void MainWindow::print()
{
    Q_ASSERT(imageLabel->pixmap());
#ifndef QT_NO_PRINTER
    QPrintDialog dialog(&printer, this);
    if (dialog.exec()) {
        QPainter painter(&printer);
        QRect rect = painter.viewport();
        QSize size = imageLabel->pixmap()->size();
        size.scale(rect.size(), Qt::KeepAspectRatio);
        painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
        painter.setWindow(imageLabel->pixmap()->rect());
        painter.drawPixmap(0, 0, *imageLabel->pixmap());
    }
#endif
}

void MainWindow::undo()
{

}

void MainWindow::redo()
{

}



void MainWindow::blur()
{
    QImage qin=imageLabel->pixmap()->toImage();
    QImage qout=Blur().convolve(&qin);
    imageLabel->setPixmap(QPixmap::fromImage(qout)); //instead, also save the prev image into an array for undo. or show in diff window.
}


void MainWindow::gaussBlur()
{
    QImage qin=imageLabel->pixmap()->toImage();
    QImage qout=GaussianBlur().convolve(&qin);
    imageLabel->setPixmap(QPixmap::fromImage(qout)); //instead, also save the prev image into an array for undo. or show in diff window.
}

void MainWindow::sharpen()
{
    Sharpen s=Sharpen();
    QImage qin=imageLabel->pixmap()->toImage();
    QImage qout=s.convolve(&qin);
    int cols=qin.width();
    int rows=qin.height();
    int i,j,R,G,B;
    for(i=0;i<cols;i++)
        for(j=0;j<rows;j++){
              R=qRed(qout.pixel(i,j));
              G=qGreen(qout.pixel(i,j));
              B=qBlue(qout.pixel(i,j));
              qout.setPixel(i,j,qRgb((R+qRed(qin.pixel(i,j)))/2,(G+qGreen(qin.pixel(i,j)))/2,(B+qBlue(qin.pixel(i,j)))/2));
    }
    imageLabel->setPixmap(QPixmap::fromImage(qout)); //instead, also save the prev image into an array for undo. or show in diff window.
}
void MainWindow::edgeDetect(){

    EdgeDetection e=EdgeDetection();
    QImage qin=imageLabel->pixmap()->toImage();
    QImage qout=e.convolve(&qin);
    imageLabel->setPixmap(QPixmap::fromImage(qout)); //instead, also save the prev image into an array for undo. or show in diff window.
}

void MainWindow::edgeDetectC()
{
    Blur b=Blur();
    EdgeDetection e=EdgeDetection();
    QImage qin=imageLabel->pixmap()->toImage();
    QImage qout=b.convolve(&qin);
    int cols=qin.width();
    int rows=qin.height();
    int i,j,R,G,B;
    for(i=0;i<cols;i++)
        for(j=0;j<rows;j++){
              R=qRed(qout.pixel(i,j));
              G=qGreen(qout.pixel(i,j));
              B=qBlue(qout.pixel(i,j));
              qout.setPixel(i,j,qRgb((-R+qRed(qin.pixel(i,j))),(-G+qGreen(qin.pixel(i,j))),(-B+qBlue(qin.pixel(i,j)))));
    }
    imageLabel->setPixmap(QPixmap::fromImage(qout)); //instead, also save the prev image into an array for undo. or show in diff window.
}

void MainWindow::sobel()
{
    QImage qin=imageLabel->pixmap()->toImage();
    SobelFilter sf=SobelFilter();
    struct _sobel_arr sob_sob_arr=sf.sobel_arr(&qin);    
    imageLabel->setPixmap(QPixmap::fromImage(sf.normalize(sob_sob_arr.R,sob_sob_arr.G,sob_sob_arr.B)));
}

void MainWindow::emboss()
{
    Emboss e=Emboss();
    QImage qin=imageLabel->pixmap()->toImage();
    QImage qout=e.convolve(&qin);
    int cols=qin.width();
    int rows=qin.height();
    int i,j,R,G,B;
    for(i=0;i<cols;i++)
        for(j=0;j<rows;j++){
              R=qRed(qout.pixel(i,j));
              G=qGreen(qout.pixel(i,j));
              B=qBlue(qout.pixel(i,j));
              qout.setPixel(i,j,qRgb((R+qRed(qin.pixel(i,j)))/2,(G+qGreen(qin.pixel(i,j)))/2,(B+qBlue(qin.pixel(i,j)))/2));
    }
    imageLabel->setPixmap(QPixmap::fromImage(qout)); //instead, also save the prev image into an array for undo. or show in diff window.
}


void MainWindow::about()
{
    QString text = "<p>" + tr("The <b>Luvlena Image Editor</b> is a student project "
                      "for the Mosig Masters course at Grenoble universities.") + "</p>";
    text += "<p>" "The students involved in this project are : " "</p>"
            "<center >Amr Najjar <br>"
            "Arun Shivanandan <br>"
            "Daniel R&iacute;os Pav&iacute;a <br>"
            "Thomas Vincent-Sweet </center>";
    QMessageBox::about(this, tr("About Luvlena Image Editor"), text);
}

void MainWindow::createActions()
{
    openAct = new QAction(tr("&Open..."), this);
    openAct->setShortcut(tr("Ctrl+O"));
    connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

    printAct = new QAction(tr("&Print..."), this);
    printAct->setShortcut(tr("Ctrl+P"));
    printAct->setEnabled(false);
    connect(printAct, SIGNAL(triggered()), this, SLOT(print()));

    saveAct = new QAction(tr("&Save"), this);
    saveAct->setShortcut(tr("Ctrl+S"));
    saveAct->setEnabled(false);
    connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));

    quitAct = new QAction(tr("Q&uit"), this);
    quitAct->setShortcut(tr("Ctrl+Q"));
    connect(quitAct, SIGNAL(triggered()), this, SLOT(close()));

    undoAct = new QAction(tr("&Undo"), this);
    undoAct->setShortcut(tr("Ctrl+Z"));
    connect(undoAct, SIGNAL(triggered()), this, SLOT(undo()));

    redoAct = new QAction(tr("&Redo"), this);
    redoAct->setShortcut(tr("Ctrl+Shift+Z"));
    connect(redoAct, SIGNAL(triggered()), this, SLOT(redo()));
    
    toolboxAct = new QAction(tr("Toolbox"), this);
    toolboxAct->setEnabled(true);
    toolboxAct->setCheckable(true);
    toolboxAct->setShortcut(tr("F9"));

    blurAct = new QAction(tr("&Blur"), this);
    connect(blurAct, SIGNAL(triggered()), this, SLOT(blur()));

    gaussBlurAct = new QAction(tr("&Gaussian Blur"), this);
    connect(gaussBlurAct, SIGNAL(triggered()), this, SLOT(gaussBlur()));

    sharpenAct = new QAction(tr("&Sharpen"), this);
    connect(sharpenAct, SIGNAL(triggered()), this, SLOT(sharpen()));

    edgeDetectAct = new QAction(tr("&Convolve"), this);
    connect(edgeDetectAct, SIGNAL(triggered()), this, SLOT(edgeDetect()));

    edgeDetectCAct = new QAction(tr("&Subtract Blur"), this);
    connect(edgeDetectCAct, SIGNAL(triggered()), this, SLOT(edgeDetectC()));

    sobelAct = new QAction(tr("&Sobel"), this);
    connect(sobelAct, SIGNAL(triggered()), this, SLOT(sobel()));

    embossAct = new QAction(tr("&Emboss Edges"), this);
    connect(embossAct, SIGNAL(triggered()), this, SLOT(emboss()));

    aboutAct = new QAction(tr("&About"), this);
    connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));

    aboutQtAct = new QAction(tr("About &Qt"), this);
    connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
}

void MainWindow::createMenus()
{
    fileMenu = new QMenu(tr("&File"), this);
    fileMenu->addAction(openAct);
    fileMenu->addAction(printAct);
    fileMenu->addSeparator();
    fileMenu->addAction(saveAct);
    fileMenu->addSeparator();
    fileMenu->addAction(quitAct);

    editMenu = new QMenu(tr("&Edit"), this);
    editMenu->addAction(undoAct);
    editMenu->addAction(redoAct);

    viewMenu = new QMenu(tr("&View"), this);
    viewMenu->addAction(toolboxAct);

    blurMenu = new QMenu(tr("&Blur"), this);
    blurMenu->addAction(blurAct);
    blurMenu->addAction(gaussBlurAct);

    sharpenMenu = new QMenu(tr("&Sharpen"), this);
    sharpenMenu->addAction(sharpenAct);

    edgeDetectMenu = new QMenu(tr("&Detect Edges"), this);
    edgeDetectMenu->addAction(sobelAct);
    edgeDetectMenu->addAction(edgeDetectCAct);
    edgeDetectMenu->addAction(edgeDetectAct);
    edgeDetectMenu->addAction(embossAct);

    filtersMenu = new QMenu(tr("&Filters"), this);
    filtersMenu->addMenu(blurMenu);
    filtersMenu->addMenu(sharpenMenu);
    filtersMenu->addMenu(edgeDetectMenu);

    helpMenu = new QMenu(tr("&Help"), this);
    helpMenu->addAction(aboutAct);
    helpMenu->addAction(aboutQtAct);

    menuBar()->addMenu(fileMenu);
    menuBar()->addMenu(editMenu);
    menuBar()->addMenu(viewMenu);
    menuBar()->addMenu(filtersMenu);
    menuBar()->addMenu(helpMenu);
}

void MainWindow::updateActions()
{
    //nothing yet
}
